/*
 * Copyright (c) 2006-2021, Halo team
 *
 * SPDX-License-Identifier: GPLv3
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-09-11     Eywen        the first version
 */
#ifndef APPLICATIONS_DRIVERS_DRV_PID_H_
#define APPLICATIONS_DRIVERS_DRV_PID_H_

#include "common.h"

typedef enum _pid_type{
    pid_type_position,            /* 位置式pid */
    pid_type_increment,           /* 增量式pid */
}pid_type_t;

/* pid基本参数 */
typedef struct _pid_base{
    float err;
    float last_err;
    float integral;
}pid_base_t;

/* 位置式PID参数 */
typedef struct _pid_para{
    float kp;
    float ki;
    float kd;
}pid_para_t;

/* 输出限制 */
typedef struct _pid_output_limit{
    float max;
    float min;
}pid_limit_t;

typedef struct _pid_ops pid_ops_t;

typedef struct _pid_{
    pid_type_t type;            /* pid类型 */
    pid_base_t pid_base;             /* pid参数 */
    pid_limit_t limit;          /* pid输出限制 */
    float target;               /* 目标值 */
    pid_para_t pid_para;
    const pid_ops_t *ops;
    float output;               /* pid输出值 */
    void *pid_type_base;        /* 与pid类型相关的参数 */
}pid_control_t;

typedef struct _pid_ops{
    bool (*init)(pid_control_t *pid, float kp, float ki,
                         float kd, float max, float min,...);
    float (*diff)(pid_control_t *device);
    float (*run_once)(pid_control_t *device, float cur);
    float (*output)(pid_control_t *pid);
    void  (*para_set)(pid_control_t *pid, pid_para_t pid_para);
    void  (*target_set)(pid_control_t *device, float target);
    float (*target)(pid_control_t *device);
    pid_limit_t (*limit)(pid_control_t *pid);
    void (*limit_set)(pid_control_t *pid, pid_limit_t limit);
}pid_ops_t;

bool pid_register(pid_control_t *pid, pid_type_t pid_type);
pid_control_t *pid_control_create(pid_type_t type);

#endif /* APPLICATIONS_DRIVERS_DRV_PID_H_ */
